package com.mf.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mf.entity.bo.PermissionByRoleBo;
import com.mf.enums.ActionTypeEnum;
import com.mf.mapper.PermissionByRoleMapper;
import com.mf.mapper.PermissionMapper;
import com.mf.service.IPermissionService;
import io.github.heollhai.common.config.exceptions.GraceException;
import io.github.heollhai.common.entity.bo.PermissionBo;
import io.github.heollhai.common.entity.request.publicRequest.PublicBindingIdRequest;
import io.github.heollhai.common.entity.vo.permissionTree.RouteVo;
import io.github.heollhai.common.enums.EnableOrDisableEnum;
import io.github.heollhai.common.utils.MybatisPlusUtils;
import io.github.heollhai.common.utils.VerifyUtils;
import io.github.heollhai.common.utils.tree.TreeUtils;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 权限表 服务实现类
 *
 * @author mf
 * @since 2024-08-06
 */
@Service
public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, PermissionBo> implements IPermissionService {

    @Resource
    private PermissionMapper permissionMapper;

    @Resource
    private PermissionByRoleMapper permissionByRoleMapper;

    @Override
    @Transactional
    public Boolean submit(PermissionBo permissionBo) {
        permissionMapper.insert(permissionBo);
        if (VerifyUtils.isNotEmpty(permissionBo.getPid()) && permissionBo.getPid() != 0) {
            setChildrenNumber(permissionBo.getPid(), "add");
        }
        return null;
    }



    /**
     * 根据角色id查询权限
     */
    @Override
    public List<Integer> findListByRoleId(Integer roleId) {
        LambdaQueryWrapper<PermissionByRoleBo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PermissionByRoleBo::getRoleId, roleId);
        List<PermissionByRoleBo> permissionByRoleBos = permissionByRoleMapper.selectList(wrapper);
        return permissionByRoleBos.stream().map(PermissionByRoleBo::getPermissionId).toList();
    }


    /**
     * 设置子级数量
     */
    @Transactional
    public void setChildrenNumber(Integer pid, String actionType) {
        if (pid != 0) {
            LambdaQueryWrapper<PermissionBo> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(PermissionBo::getId, pid)
                    .eq(PermissionBo::getStatus, EnableOrDisableEnum.ENABLE.value);
            PermissionBo permissionBo = permissionMapper.selectOne(wrapper);
            if (VerifyUtils.isEmpty(permissionBo)) {
                GraceException.display("父级id不存在");
            }

            if ("add".equals(actionType)) {
                permissionBo.setChildrenNumber(permissionBo.getChildrenNumber() + 1);
            } else {
                if (permissionBo.getChildrenNumber() < 1) {
                    GraceException.display("子级数量不能小于0");
                }
                permissionBo.setChildrenNumber(permissionBo.getChildrenNumber() - 1);
            }
            permissionMapper.updateById(permissionBo);
        }
    }

    /**
     * 查询所有权限
     */
    @Override
    public List<PermissionBo> findListPermission() {
        LambdaQueryWrapper<PermissionBo> queryWrapper = new LambdaQueryWrapper<>();
        return permissionMapper.selectList(queryWrapper);
    }

    /**
     * 查询菜单权限(树结构)
     */
    @Override
    public List<RouteVo> findTreeMenuList() {
        LambdaQueryWrapper<PermissionBo> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(PermissionBo::getActionType, ActionTypeEnum.MENU.value, ActionTypeEnum.MENU_PUBLIC.value);

        List<PermissionBo> permissionBos = permissionMapper.selectList(wrapper);
        List<RouteVo> routeVos = MybatisPlusUtils.changeDataClass(permissionBos, RouteVo.class);
        return TreeUtils.getRoot(routeVos);
    }
    /**
     *  根据角色id绑定权限
     */
    @Override
    @Transactional
    public Integer permissionIdsBindingRoleId(PublicBindingIdRequest bindingIdRequest) {
        // 删除角色id绑定的权限
        permissionByRoleMapper.deleteByRoleId(bindingIdRequest.getTargetId());
        // 绑定新的权限
        return permissionByRoleMapper.insertBatch(bindingIdRequest);
    }

    /**
     * 查询所有权限(树结构)
     */
    @Override
    public List<RouteVo> findTreeList() {
        List<PermissionBo> permissionBos = permissionMapper.selectList(null);
        List<RouteVo> routeVos = MybatisPlusUtils.changeDataClass(permissionBos, RouteVo.class);
        return TreeUtils.getRoot(routeVos);
    }

    /**
     * 根据权限id删除权限
     */
    @Override
    @Transactional
    public Integer deleteById(Integer permissionId) {
        List<String> RoleNames = permissionByRoleMapper.selectListByPermissionId(permissionId);
        if (VerifyUtils.isNotEmpty(RoleNames)) {
            GraceException.display("该权限已被绑定角色" + RoleNames + "，无法删除");
        }

        PermissionBo permissionBo = permissionMapper.selectById(permissionId);
        if (VerifyUtils.isNotEmpty(permissionBo.getPid()) && permissionBo.getPid() != 0) {
            // 更新子级数量
            setChildrenNumber(permissionBo.getPid(), "subtract");
            permissionMapper.updateById(permissionBo);
        }

        // 如果有子级，则不能删除
        if (permissionBo.getChildrenNumber() > 0) {
            GraceException.display("该权限有子级，无法删除");
        }



        return permissionMapper.deleteById(permissionId);
    }

    /**
     * @return 根据父级id查询
     */
    @Override
    public List<PermissionBo> findByPid(Integer pid) {
        LambdaQueryWrapper<PermissionBo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PermissionBo::getPid, pid)
                .orderByDesc(PermissionBo::getSort)
        ;

        return permissionMapper.selectList(wrapper);
    }
}
